package com.rjkj.medicalwaste.base

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rjkj.medicalwaste.bean.GarbageBean
import com.rjkj.medicalwaste.bean.GarbageStatus
import com.rjkj.medicalwaste.bean.GarbageStatus.loading
import com.rjkj.medicalwaste.bean.MedicalWasteType
import com.rjkj.medicalwaste.bean.UserBean
import com.rjkj.medicalwaste.network.response.ApiException
import com.rjkj.medicalwaste.network.response.BaseResponse
import com.rjkj.medicalwaste.network.response.catchException
import com.rjkj.medicalwaste.network.response.next
import com.rjkj.medicalwaste.network.retrofit.Api
import com.rjkj.medicalwaste.network.retrofit.ApiInterface
import com.rjkj.medicalwaste.utils.AppPrefsUtils
import com.rjkj.medicalwaste.utils.BaseConstant
import com.rjkj.medicalwaste.utils.TimeUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException

fun addOneGarbage(
    code: String,
    weight: String,
    medicalWasteType: MedicalWasteType,
    hospitalIdStr: String,
    hospitalName: String,
    user: UserBean,
    nurse: UserBean,
    department: UserBean,
    garbageDeviceSN: String,
    fromControlBox: Boolean = false,
    garbageCount: Int = 0
): GarbageBean {
    val time = TimeUtils.getYMDHMSTime()
    val garbageBean = GarbageBean(
        garbageDeviceSN = garbageDeviceSN,
        garbageWeight = weight,
        garbageQRCode = code,
        garbageType = medicalWasteType.typeName,
        hospitalId = hospitalIdStr,
        hospitalName = hospitalName,
        nurseQRCode = nurse.qrcode,
        nurseQRName = nurse.name,
        departmentName = department.name,
        departmentQRCode = department.qrcode,
        cleanerQRCode = user.qrcode,
        cleanerName = user.name,
        garbageUserStatus = GarbageStatus.collect,
        garbageTime = time,
        garbageChangeTime = time,
        garbageCount = garbageCount
    )
    garbageBean.fromControlBox = fromControlBox
    return garbageBean
}

open class BaseViewModel : ViewModel() {
    val TAG = "XLB"
    val loadingEvent = MutableLiveData<Boolean>()
    val uploadEvent = MutableLiveData<Boolean>()
    val tips = MutableLiveData<String?>()


    /**
     * Helper function to call a data load function with a loading spinner, errors will trigger a
     * snackbar.
     *
     * By marking `block` as `suspend` this creates a suspend lambda which can call suspend
     * functions.
     *
     * @param block lambda to actually load data. It is called in the viewModelScope. Before calling the
     *              lambda the loading spinner will display, after completion or error the loading
     *              spinner will stop
     */
    fun launchDataLoad(block: suspend () -> Unit): Unit {
        viewModelScope.launch {
            try {
                block()
            } catch (error: Exception) {
                error.printStackTrace()
                tips.value = error.message
            } finally {

            }
        }
    }

    fun onSnackBarShown() {
        tips.value = null
    }

    /**
     * 简单的请求，没有加try-catch捕获异常，使用的时候切记！！！！！需要手动try-catch或使用runCatching方法捕获
     * @receiver BaseViewModel
     * @param request [@kotlin.ExtensionFunctionType] SuspendFunction1<ApiInterface, BaseResponse<T>?>
     * @return BaseResponse<T>
     */
    suspend fun <T> requestSimple(request: suspend ApiInterface.() -> BaseResponse<T>?): BaseResponse<T> {
        /*withContext表示挂起块  配合Retrofit声明的suspend函数执行 该块会挂起直到里面的网络请求完成 最一行就是返回值*/
        val response = withContext(Dispatchers.IO) {
            request(Api)
        } ?: throw IllegalArgumentException("数据非法，获取响应数据为空")
        if (response.code != 200) {
            throw  ApiException(response.code, response.message ?: "")
        }
        return response
    }

    suspend fun <T> request(
        showLoading: Boolean = true,
        io: Boolean = false,
        request: suspend ApiInterface.() -> BaseResponse<T>?
    ): BaseResponse<T> {
        return try {
            if (showLoading) {
                if (io) {
                    showLoadingP()
                } else
                    showLoadingP()
            }
            requestSimple(request)
        } catch (e: Exception) {
            BaseResponse<T>().apply {
                exception = e
            }
        } finally {
            if (showLoading) {
                if (io) {
                    closeLoadingP()
                } else
                    closeLoadingP()

            }
        }
    }


    fun showLoading() {
        loadingEvent.value = true
    }

    fun closeLoading() {
        Log.e(TAG, "closeLoading: ")
        loadingEvent.value = false
    }

    fun showLoadingP() {
        loadingEvent.postValue(true)
    }

    fun closeLoadingP() {
        Log.e(TAG, "closeLoading: ")
        loadingEvent.postValue(false)
    }

    fun doException(exception: Exception) {
        when (exception) {
            is ApiException -> {
                tips.value = exception.message
                Log.e(TAG, ": ${exception.message}")
            }
            is IllegalArgumentException ->
                Log.e(TAG, "非法状态")
        }

    }





//    /**
//     * 请求网络
//     */
//    fun requestData(){
//        viewModelScope.launch {
//            request(false) {
//                getListProject();
//            }.next {
//                Log.e("data===>","data=====>${this.data}")
//                responseText.set(this.data.toString())
//            }.catchException {
//                when(this){
//                    is ApiException->{
//
//                    }
//                    is IOException->{
//
//                    }
//                    else->{
//
//                    }
//                }
//            }
//        }
//    }
//
//    /**
//     * 轮询
//     */
//    fun requestLoopData(){
//        viewModelScope.launch {
//            runCatching {
//                while (true) {
//                    requestSimple {
//                        getListProject();
//                    }.next {
//                        Log.e("data===>","requestLoopData=====>${this.data}")
//                    }
//                    delay(1 * 1000)//1s请求一次
//                }
//
//            }
//        }
//
//    }

}